package com.xyf.sys.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONArray;
import com.xyf.sys.config.CustomException;
import com.xyf.sys.domain.*;
import com.xyf.sys.mapper.SysCartMapper;
import com.xyf.sys.service.*;
import com.xyf.sys.vo.CartItemAdd;
import com.xyf.sys.vo.CartOrderResponse;
import com.xyf.sys.vo.PreOrderResponseVo;
import com.xyf.sys.vo.ShareOrder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;

import static com.xyf.sys.service.impl.OrderServiceImpl.convertToFixedLengthHash;

/**
 * @Author R-H
 * @Date 2024/4/151826
 * @Description
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class ICartServiceImpl implements ICartService {

    private static final int CART_NUMBER_LENGTH = 6;
    private static final String UPPER_CASE_ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    @Autowired
    private SysCartMapper cartMapper;
    @Autowired
    private IProductService productService;
    @Lazy
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ICartItemService cartItemService;
    @Autowired
    private IUserAddressService userAddressService;
    @Autowired
    private IOrderAddressService orderAddressService;
    @Autowired
    private IProductOptionService productOptionService;
    @Autowired
    private IOrderProductService orderProductService;

    @Override
    public List<SysCart> list(String userId, Integer type, boolean client) {
        List<SysCart> list = cartMapper.selectList(userId, type);
        for (SysCart cart : list) {
            List<SysCartItem> cartItemList = cartItemService.getCartItemList(cart.getId());
            for (SysCartItem cartItem : cartItemList) {
                SysProduct product = productService.get(cartItem.getProductId());
                Long id = cartItem.getId();
                BeanUtils.copyProperties(product, cartItem);
                cartItem.setId(id);
                cart.setItemList(cartItemList);
            }
            if (cart.getType() != null && cart.getType() == 1 && cart.getShareCartId() != null) {
                String regimentId = cart.getRegimentId();
                User user = userService.get(regimentId);
                cart.setShareName(user.getName());
                cart.setShareMobile(user.getMobile());
            }
            cart.setItemList(cartItemList);
        }
        return list;
    }

    @Override
    public SysCart get(Long id) {
        return cartMapper.selectByPrimaryKey(id);
    }

    @Override
    public SysCart getUserCart(Long id, String userId, boolean client) {
        if (StringUtils.isBlank(userId)) {
            throw new CustomException("参数缺失");
        }
        SysCart cart = id != null ? this.get(id) : getDefaultCart(userId, client);
        List<SysCartItem> cartItemList = cartItemService.getCartItemList(cart.getId());
        if (!CollectionUtils.isEmpty(cartItemList)) {
            for (SysCartItem cartItem : cartItemList) {
                SysProduct product = productService.get(cartItem.getProductId());
                Long cartItemId = cartItem.getId();
                BeanUtils.copyProperties(product, cartItem);
                cartItem.setId(cartItemId);
            }
        }
        cart.setItemList(cartItemList);
        return cart;
    }

    @Override
    public int update(SysCart cart) {
        cart.setUpdateTime(new Date());
        cart.setLastUpdateTime(new Date());
        return cartMapper.updateByPrimaryKey(cart);
    }

    @Override
    public int delete(Long id) {
        return cartMapper.deleteByPrimaryKey(id);
    }

    @Override
    public Order createPreOrder(Long cartId, String userId, String appid) {
        if (cartId == null) {
            throw new CustomException("参数异常");
        }
        SysCart cart = cartMapper.selectByPrimaryKey(cartId);
        if (cart == null) {
            throw new CustomException("数据异常");
        }
        User user = userService.get(userId);
        List<SysCartItem> cartItemList = cartItemService.getCartItemList(cart.getId());
        List<SysCartItem> selectedList = cartItemList.stream().filter(cartItem -> cartItem.getSelected() == 1).collect(Collectors.toList());
        cart.setItemList(selectedList);
//        Order order = orderService.createCartOrder(Arrays.asList(cart), userId, user.getRegimentId(), appid);
        selectedList.stream().forEach(cartItem -> {
            cartItem.setStatus("1");
            cartItemService.update(cartItem);
        });
        cart.setStatus("3");
        this.update(cart);
//        return order;
        return null;
    }

    @Override
    public SysCart getDefaultCart(String userId, boolean client) {
        SysCart cart = cartMapper.selectUserDefault(userId);
        String regimentId = null;
        if (client) {
            User user = userService.get(userId);
            regimentId = user.getRegimentId();
        } else {
            regimentId = userId;
        }
        return cart == null ? createDefaultEmptyCart(userId, regimentId, 0) : cart;
    }

    @Override
    public SysCart createDefaultEmptyCart(String userId, String regimentId, Integer type) {
        SysCart cart = new SysCart();
        cart.setCode(generateCode());
        cart.setStatus("0");
        cart.setUserId(userId);
        cart.setRegimentId(regimentId);
        cart.setType(type);
        cart.setNum(0);
        cart.setTotalPrice(BigDecimal.ZERO);
        cart.setTimestamp(new Date());
        cart.setCreateTime(new Date());
        cart.setCreateBy(userId);
        cart.setDelFlag("0");
        cartMapper.insert(cart);
        return cart;
    }

    @Override
    public SysCart add(SysCartItem cartItem) {
        User user = userService.get(cartItem.getUserId());
        SysCartItem item = null;
        if (cartItem.getId() != null) {
            item = this.cartItemService.get(cartItem.getId());
        } else {
            item = cartItem;
        }
        item.setRegimentId(user.getRegimentId());
        item.setQuantity(cartItem.getQuantity() == null ? 1 : cartItem.getQuantity());
        item.setColorId(JSONArray.toJSONString(cartItem.getColorIds()));
        item.setServeId(JSONArray.toJSONString(cartItem.getServeIds()));
        item.setDefectId(JSONArray.toJSONString(cartItem.getDefectIds()));
        item.setAffixId(JSONArray.toJSONString(cartItem.getAffixIds()));
        BigDecimal servePrice = BigDecimal.ZERO;
        if (StringUtils.isNotBlank(item.getColorId())){
            List<Long> colorIds = JSONArray.parseArray(item.getColorId(), Long.class);
            List<SysProductOption> colorOptions = productOptionService.getList(colorIds);
            if (!CollectionUtils.isEmpty(colorOptions)){
                for (SysProductOption colorOption : colorOptions) {
                    if (colorOption.getPrice() != null){
                        servePrice = servePrice.add(colorOption.getPrice());
                    }
                }
            }
        }
        if (StringUtils.isNotBlank(item.getServeId())){
            List<Long> serveIds = JSONArray.parseArray(item.getServeId(), Long.class);
            List<SysProductOption> serveOptions = productOptionService.getList(serveIds);
            if (!CollectionUtils.isEmpty(serveOptions)){
                for (SysProductOption colorOption : serveOptions) {
                    if (colorOption.getPrice() != null){
                        servePrice = servePrice.add(colorOption.getPrice());
                    }
                }
            }
        }
        if (StringUtils.isNotBlank(item.getDefectId())){
            List<Long> defectIds = JSONArray.parseArray(item.getDefectId(), Long.class);
            List<SysProductOption> defectOptions = productOptionService.getList(defectIds);
            if (!CollectionUtils.isEmpty(defectOptions)){
                for (SysProductOption colorOption : defectOptions) {
                    if (colorOption.getPrice() != null){
                        servePrice = servePrice.add(colorOption.getPrice());
                    }
                }
            }
        }
        if (StringUtils.isNotBlank(item.getAffixId())){
            List<Long> affixIds = JSONArray.parseArray(item.getAffixId(), Long.class);
            List<SysProductOption> affixOptions = productOptionService.getList(affixIds);
            if (!CollectionUtils.isEmpty(affixOptions)){
                for (SysProductOption colorOption : affixOptions) {
                    if (colorOption.getPrice() != null){
                        servePrice = servePrice.add(colorOption.getPrice());
                    }
                }
            }
        }
        BigDecimal price = productService.get(item.getProductId()).getPrice();
        BigDecimal total = price.multiply(new BigDecimal(item.getQuantity()));
        total = total.add(servePrice);
        item.setPricePerUnit(price);
        item.setServePrice(servePrice);
        item.setTotalPrice(total);
        item.setImg(cartItem.getImg());
        item.setStatus("0");
        item.setDelFlag("0");
        if (item.getId() == null) {
            item.setCreateBy(cartItem.getUserId());
            item.setCreateTime(new Date());
            cartItemService.insert(item);
        } else {
            item.setUpdateBy(cartItem.getUserId());
            item.setUpdateTime(new Date());
            cartItemService.update(item);
        }
        List<SysCartItem> cartItemList = cartItemService.getCartItemList(item.getUserId());
        BigDecimal sum = BigDecimal.ZERO;
        for (SysCartItem sysCartItem : cartItemList) {
            sum = sum.add(sysCartItem.getTotalPrice());
        }
        SysCart cart = new SysCart();
        cart.setNum(cartItemList.size());
        cart.setTotalPrice(sum);
        if (StringUtils.isNotBlank(cartItem.getOrderId())){
            Order order = orderService.get(cartItem.getOrderId());
            if (order == null){
                throw new CustomException("数据错误");
            }
            OrderProduct orderProduct = new OrderProduct();
            long id = IdUtil.getSnowflakeNextId();
            orderProduct.setId(String.valueOf(id));
            orderProduct.setCode(convertToFixedLengthHash(id));
            orderProduct.setOrderId(order.getId());
            orderProduct.setUserId(cartItem.getUserId());
            orderProduct.setCartItemId(cartItem.getId());
            orderProduct.setProductId(cartItem.getProductId());
            orderProduct.setTotalPrice(total);
            orderProduct.setPickUpPrice(BigDecimal.ZERO);
            orderProduct.setLastUpdateTime(new Date());
            orderProduct.setCreateTime(new Date());
            orderProduct.setStatus("0");
            orderProduct.setDelFlag("0");
            orderProductService.save(orderProduct);
            order.setTotalPrice(sum);
            order.setUpdateBy(cartItem.getUserId());
            orderService.update(order);
        }
        return cart;
    }


    @Override
    public SysCart update(SysCartItem item) {
        if (item.getId() == null) {
            throw new CustomException("参数缺失");
        }
        SysCartItem data = cartItemService.get(item.getId());
        if (data == null || item.getQuantity() == null || item.getQuantity() < 1) {
            throw new CustomException("参数错误");
        }
        SysCart cart = this.get(data.getCartId());
        data.setQuantity(item.getQuantity());
        cartItemService.update(data);
        this.collectCart(cart);
        cart.setUpdateBy(item.getUserId());
        this.update(cart);
        return cart;
    }

    @Override
    public void deleteItem(Long id, String orderId, String userId) {
        if (id == null) {
            throw new CustomException("参数缺失");
        }
        SysCartItem data = cartItemService.get(id);
        if (data == null) {
            throw new CustomException("参数错误");
        }
        cartItemService.delete(data.getId());
        if (StringUtils.isNotBlank(orderId)){
            Order order = orderService.get(orderId);
            List<OrderProduct> productList = orderProductService.getOrderProductList(orderId);
            Optional<OrderProduct> optional = productList.stream().filter(orderProduct -> id.equals(orderProduct.getCartItemId())).findAny();
            if (!optional.isPresent()){
                throw new CustomException("参数错误");
            }
            OrderProduct orderProduct = optional.get();
            orderProduct.setDelFlag("1");
            orderProduct.setUpdateBy(userId);
            orderProductService.update(orderProduct);
            order.setTotalPrice(order.getTotalPrice().subtract(orderProduct.getTotalPrice()));
            order.setUpdateBy(userId);
            orderService.update(order);
        }
    }

    @Override
    public void clear(Long cartId, String userId) {
        SysCart cart = cartMapper.selectByPrimaryKey(cartId);
        List<SysCartItem> cartItemList = cartItemService.getCartItemList(cartId);
        cartItemList.stream().forEach(cartItem -> {
            cartItem.setDelFlag("1");
            cartItem.setUpdateBy(userId);
            cartItem.setUpdateTime(new Date());
            cartItemService.update(cartItem);
        });
        cart.setDelFlag("1");
        cart.setUpdateBy(userId);
        this.update(cart);
    }

    @Override
    public CartOrderResponse shareOrder(ShareOrder cartShare) {
        Order order = orderService.get(cartShare.getOrderId());
        if (order == null){
            order = orderService.getByCode(cartShare.getOrderId());
        }
        if (order == null) {
            throw new CustomException("数据异常");
        }
        if (order.getUserId() != null && StringUtils.isNotBlank(order.getTransactionId())){
            throw new CustomException("分享码已失效");
        }
        UserAddress receiverAddress = cartShare.getRecMan();
        Long receiverAddressId = cartShare.getReceiverAddressId();
        if (receiverAddress == null) {
            receiverAddress = userAddressService.get(receiverAddressId);
        }
        User user = userService.get(order.getRegimentId());
        order.setUserId(cartShare.getUserId());
        if (receiverAddress != null){
            OrderAddress receiverOrderAddress = new OrderAddress();
            receiverOrderAddress.setMobile(receiverAddress.getMobile());
            receiverOrderAddress.setOrderId(order.getId());
            receiverOrderAddress.setUserId(order.getUserId());
            receiverOrderAddress.setProvince(receiverAddress.getProvince());
            receiverOrderAddress.setCity(receiverAddress.getCity());
            receiverOrderAddress.setArea(receiverAddress.getArea());
            receiverOrderAddress.setAddress(receiverAddress.getAddress());
            receiverOrderAddress.setName(receiverAddress.getName());
            receiverOrderAddress.setType(2);
            receiverOrderAddress.setLastUpdateTime(new Date());
            receiverOrderAddress.setCreateBy(order.getUserId());
            receiverOrderAddress.setCreateTime(new Date());
            receiverOrderAddress.setStatus("0");
            receiverOrderAddress.setDelFlag("0");
            orderAddressService.save(receiverOrderAddress);
        }
        orderService.update(order);
        PreOrderResponseVo pay = null;
        if (BigDecimal.ZERO.compareTo(order.getTotalPrice()) == -1 && order.getPayStatus() == 0) {
             pay = orderService.pay(order.getId(), cartShare.getUserId(), cartShare.getAppid());
        }
        return new CartOrderResponse(orderService.getDetail(order.getId()), pay);
    }

    @Override
    public void collectCart(SysCart cart) {
        List<SysCartItem> cartItemList = cartItemService.getCartItemList(cart.getId());
        List<SysCartItem> selectedList = cartItemList.stream().filter(item -> 1 == item.getSelected()).collect(Collectors.toList());
        Integer num = 0;
        BigDecimal total = BigDecimal.ZERO;
        for (SysCartItem item : selectedList) {
            num += item.getQuantity();
            total = total.add(item.getTotalPrice());
        }
        cart.setNum(num);
        cart.setTotalPrice(total);
    }

    @Override
    public Order preShare(ShareOrder share) {
        SysCart cart = cartMapper.selectByPrimaryKey(share.getCartId());
        if (cart == null) {
            throw new CustomException("数据异常");
        }
        cart.setStatus("1");
        cart.setUpdateBy(share.getUserId());
        this.update(cart);
        return createPreOrder(cart.getId(), share.getUserId(), share.getAppid());
    }

    @Override
    public String generateCode() {
        StringBuilder cartNumber = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < CART_NUMBER_LENGTH; i++) {
            int randomIndex = random.nextInt(UPPER_CASE_ALPHABETS.length());
            char randomChar = UPPER_CASE_ALPHABETS.charAt(randomIndex);
            cartNumber.append(randomChar);
        }
        String code = cartNumber.toString();
        if (cartMapper.countCode(code) == 0) {
            return code;
        }
        return generateCode();
    }

    @Override
    public List<SysCart> getShareList(String userId, Long cartId, String status) {
        return cartMapper.selectByUserIdAndShareCartId(userId, cartId, status);
    }
}
